class Dropdown {
  value = null;
  label = null;
  data = null;
  instance = null;
  trigger = null;
  dataMap = new Map();
  constructor(el, option = {}) {
    const options = Object.assign(
      {
        value: "value",
        label: "label",
        data: [],
      },
      option
    );
    const { value, label, data, callback, tag } = options;
    this.data = data;
    this.data.forEach((v) => {
      this.dataMap.set(v.value, v);
    });
    this.value = value;
    this.label = label;
    this.trigger = el;
    const rect = el.getBoundingClientRect();
    const bodyPosition = document.body.getBoundingClientRect()
    const dropDownInstance = document.createElement("div");
    dropDownInstance.innerHTML = `
    ${data
      .map((v) => {
        return `<div class="dropdown-item" data-id="${v[value]}">${
          v.icon
            ? `<span data-id="${v[value]}" class="icon-${v.icon} dropdown-item-icon"></span>`
            : ``
        }<span data-id="${v[value]}" class="dropdown-item-text">${
          v[label]
        }</span></div>`;
      })
      .join("")}
    `;
    dropDownInstance.addEventListener("click", (e) => {

      if (
        e.target.className.indexOf("dropdown-item") !== -1 ||
        e.target.className.indexOf("dropdown-item-icon") !== -1 ||
        e.target.className.indexOf("dropdown-item-text") !== -1
      ) {
        if (callback) {
          const value = e.target.dataset.id;
          callback(this.dataMap.get(value));
        }
        if (tag) {
          this.hidden();
        } else {
          this.remove();
        }
      }
    });
    dropDownInstance.style.top = "0px";
    dropDownInstance.className = "dropdown";
    dropDownInstance.style.left = "0px";

    const Height = 32 * data.length
    if(Height+rect.top>bodyPosition.top+bodyPosition.height){
      dropDownInstance.style.transform = `translate(${rect.left}px,${
        rect.top -Height - rect.height - 4
      }px)`;
    }else{
      dropDownInstance.style.transform = `translate(${rect.left}px,${
        rect.top + rect.height + 4
      }px)`;
    }

    this.instance = dropDownInstance;
    document.body.appendChild(dropDownInstance);
  }
  hidden = () => {
    this.instance.style.display = "none";
  };
  show = () => {
    const rect = this.trigger.getBoundingClientRect();
    const bodyPosition = document.body.getBoundingClientRect()

    const Height = 32 * this.data.length
    if(Height+rect.top>bodyPosition.top+bodyPosition.height){
      this.instance.style.transform = `translate(${rect.left}px,${
        rect.top -Height - rect.height - 4
      }px)`;
    }else{
      this.instance.style.transform = `translate(${rect.left}px,${
        rect.top + rect.height + 4
      }px)`;
    }
    this.instance.style.display = "inline-block";
    
  };
  remove = () => {
    this.instance.parentNode.removeChild(this.instance);
  };
}
var $dropdown = (() => {
  const dropdowns = [];
  const dropdownsMap = new Map();
  /**
   * Handles showing a dropdown element based on the provided options.
   *
   * @param {HTMLElement} el - The element to show the dropdown for.
   * @param {object} option - The options for showing the dropdown.
   * @param {string} option.tag - 当前dropdown的唯一标识
   * @param {object} option.data - 数据
   * @param {Function} option.callback - 点击后回调函数
   * @return {void}
   */
  const handleShow = (el, option = {}) => {
    const { tag } = option;
    if (tag) {
      if (dropdownsMap.has(tag)) {
        const dd = dropdownsMap.get(tag);
        dd.show();
      } else {
        dropdownsMap.set(tag, new Dropdown(el, option));
      }
    } else {
      dropdowns.push(new Dropdown(el, option));
    }
  };
  const handleHidden = () => {
    dropdownsMap.forEach((dp) => {
      dp.hidden();
    });
    while (dropdowns.length > 0) {
      const dp = dropdowns.pop();
      dp.remove();
    }
  };
  return {
    show: handleShow,
    hidden: handleHidden,
  };
})();
